package com.card.game;

import java.util.Collections;
import java.util.List;
import java.util.Vector;

import com.card.game.room.SHRoom;
import com.card.main.GameConfig;
import com.card.user.User;
import com.card.user.UserUtils;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;

public class QzUtils {
	public static List<CardHeap> getCanChiList(Vector<Card> cards,Card temp) {
		if(temp.getType() > CardType.BING) {
			return null;
		}
		List<CardHeap> heapList = Lists.newArrayList();
		Card c1 = new Card(temp.getType(), temp.getIndex()-2);
		Card c2 = new Card(temp.getType(), temp.getIndex()-1);
		Card c3 = new Card(temp.getType(), temp.getIndex()+1);
		Card c4 = new Card(temp.getType(), temp.getIndex()+2);
//		if(isContains(cards, c2)) {
//			if(isContains(cards, c1) || isContains(cards, c3)) return true;
//		}
//		if(isContains(cards, c3)) {
//			if(isContains(cards, c4) || isContains(cards, c2)) return true;
//		}
		if(isContains(cards, c1) && isContains(cards, c2)) {
			heapList.add(new CardHeap(c1, c2, temp));
		}
		if(isContains(cards, c2) && isContains(cards, c3)) {
			heapList.add(new CardHeap(c3, c2, temp));
		}
		if(isContains(cards, c3) && isContains(cards, c4)) {
			heapList.add(new CardHeap(c3, c4, temp));
		}
		return heapList.isEmpty()?null:heapList;
	}
	
	private static boolean isContains(Vector<Card> cards,Card temp) {
		return temp.getIndex()>0&&temp.getIndex()<10&&cards.contains(temp);
	}
	
	public static List<Card> getTingCards(Vector<Card> cards) {
		List<Card> tings = Lists.newArrayList();
		for (Card c : AqUtils.NoFengAllCards) {
			if(isHuPai(cards, c)) {
				tings.add(c);
			}
		}
		if(!tings.isEmpty()) {
			tings.add(new Card(CardType.ZHONG, 0));
		}
		return tings;
	}
	public static boolean isHuPai(Vector<Card> sours2,Card huCard) {
		Vector<Card> clones = (Vector<Card>)sours2.clone();
		clones.add(huCard);
		return isZimo(clones, false);
	}
	
	public static boolean isZimo(Vector<Card> sours,boolean haveFeng) {
		Vector<Card> cards = (Vector<Card>)sours.clone();
		List<Card> jinCards = removeJinCard(cards);
		int size = jinCards.size();
		if(size == 0) {
			return MMHandUtils.isHuPai(cards);
		}else if(size == 1) {
			List<Integer> sour = MMHandUtils.transInteger(cards);
			return isHu1Jin(sour,haveFeng);
		}else{
			List<Integer> sour = MMHandUtils.transInteger(cards);
			if(size >=2 && size<4) {
				return isHuJin(sour,haveFeng,size);
			}
			return true;
		}
	}
	
	public static void toString(Vector<Card> sours) {
		StringBuffer sb = new StringBuffer();
		for (Card card : sours) {
			sb.append(card.getType()+"-"+card.getIndex()+";");
		}
		System.err.println(sb.toString());
	}
	
	public static boolean isHuJin(List<Integer> cards,boolean haveFeng,int jinNum) {
		ImmutableList<List<Integer>> all = JinUtils.NoFengAll3Cards;
		if(jinNum == 2) {
			all = haveFeng?JinUtils.All2Cards:JinUtils.NoFengAll2Cards;
		}
		if(jinNum == 3) {
			all = haveFeng?JinUtils.All3Cards:JinUtils.NoFengAll3Cards;
		}
		for (List<Integer> cc : all) {
			List<Integer> clone = Lists.newArrayList(cards);
			clone.addAll(cc);
			if(MMHandUtils.isHuPai(clone)) {
				return true;
			}
		}
		return false;
	}
	
	public static boolean isHu(List<Integer> cards,int temp) {
		List<Integer> clone = Lists.newArrayList(cards);
		clone.add(temp);
		return MMHandUtils.isHuPai(clone);
	}
	
	private static boolean isHu1Jin(List<Integer> cards,boolean haveFeng) {
		ImmutableList<Integer> all = JinUtils.NoFengAllCards;
		if(haveFeng) {
			all = JinUtils.AllCards;
		}
		for (int c : all) {
			if(isCanHu(cards,c) && isHu(cards, c)) {
				return true;
			}
		}
		return false;
	}
	
	
	public static List<Card> getSameCard(Vector<Card> cards,Card jinCard) {
		List<Card> temp = Lists.newArrayList();
		for (Card card : cards) {
			if(card.equals(jinCard) && !card.isOutJin()) {
				temp.add(card);
			}
		}
		return temp;
	}
	public static List<Card> removeJinCard(Vector<Card> cards) {
		List<Card> temp = Lists.newArrayList();
		for (int i = cards.size()-1; i >= 0; i--) {
			Card card = cards.get(i);
			if(card.isJinCard() && !card.isOutJin()) {
				cards.remove(i);
				temp.add(card);
			}
		}
		return temp;
	}
	
	public static boolean is3JinPai(Vector<Card> cards,Card jinPai) {
		int num = 0;
		for (Card card : cards) {
			if(card.equals(jinPai)) {
				num ++;
			}
		}
		return num>=GameConfig.JinHuNum;
	}
	
	public static List<Card> getAnYouCard(Vector<Card> cards,Card jinPai) {
		List<Card> youCards = Lists.newArrayList();
		if(cards.contains(jinPai)) {
			cards.remove(jinPai);
			List<Card> tempCards = Lists.newArrayList();
			for (int i = cards.size()-1; i >= 0; i--) {
				Vector<Card> clone = (Vector<Card>)cards.clone();
				Card cc = clone.remove(i);
				if(tempCards.contains(cc)) continue;
				tempCards.add(cc);
				if(isYoujin(clone,jinPai)) {
					youCards.add(cc);
				}
			}
		}
		return youCards;
	}
	
	public static boolean isCan2YouJin(Vector<Card> cards,Card jinPai) {
		Vector<Card> clones = (Vector<Card>)cards.clone();
		for (int i = 0; i < 2; i++) {
			if(!clones.remove(jinPai)) return false;
		}
		return isYoujin(clones,jinPai);
	} 
	
	public static boolean isCanGuangYou(Vector<Card> cards,Card outCard,Card jinPai) {
		if(cards.contains(jinPai)) {
			cards.remove(jinPai);
			return isYoujin(cards,jinPai);
		}
		return false;
	}
	
	private static boolean isYoujin(Vector<Card> clone,Card jinPai) {
		if(!clone.contains(jinPai)) {
			return isYoujin(clone);
		}
		clone.remove(jinPai);
		for (int i = CardType.WAN; i <= CardType.BING; i++) {
			for (int j = 1; j < 10; j++) {
				Card c = new Card(i, j);
				Vector<Card> card = (Vector<Card>)clone.clone();
				card.add(c);
				if(isYoujin(card)) {
					return true;
				}
			}
		}
		for (int i = CardType.DONG; i <= CardType.BAI; i++) {
			Card c = new Card(i, 0);
			Vector<Card> card = (Vector<Card>)clone.clone();
			card.add(c);
			if(isYoujin(card)) {
				return true;
			}
		}
		return false;
	}
	private static boolean isYoujin(Vector<Card> clone) {
		if(HandUtils.allIsDui(clone)) {
			return true;
		}
		Collections.sort(clone);
		Vector<Card> clone2 = (Vector<Card>)clone.clone();
		CardUtils.findSameCardBySize(clone, 3);
		CardUtils.findLinkByCards(clone);
		if(clone.isEmpty()) {
			return true;
		}
		CardUtils.findLinkByCards(clone2);
		CardUtils.findSameCardBySize(clone2, 3);
		return clone2.isEmpty();
	}
	public static boolean isCanHu(Vector<Card> cards,Card c) {
		if(cards.contains(c)) {
			return true;
		}
		if(c.getIndex() > 0) {
			if((c.getIndex() >= 2 && cards.contains(new Card(c.getType(),c.getIndex()-1)))
					|| (c.getIndex() <= 8  &&cards.contains(new Card(c.getType(),c.getIndex()+1)))
					) {
				return true;
			}
		}
		return false;
	}
	
	public static boolean isCanHu(List<Integer> cards,int c) {
		if(cards.contains(c)) {
			return true;
		}
		if(c > 0) {
			if((c%10 >= 2 && cards.contains(c-1))
					|| (c%10 <= 8 &&cards.contains(c+1))
					) {
				return true;
			}
		}
		return false;
	}
	
	public static Vector<Card> testCard(String cards) {
		Vector<Card> allCards = new Vector<>();
		String[] ss = cards.toString().split(";");
		for (int i = ss.length-1; i >= 0 ; i--) {
			String s = ss[i];
			int type = Integer.parseInt(s.split("-")[0]);
			int index = Integer.parseInt(s.split("-")[1]);
			Card c = new Card(type, index);
			allCards.add(c);
		}
		return allCards;
	}
	
	public static boolean isJiaHu(Vector<Card> sours2,Card huCard) {
		if(sours2.size() >= 4 && huCard.getIndex()>1 && huCard.getIndex()<9) {
			Vector<Card> clones = (Vector<Card>)sours2.clone();
			if(clones.remove(new Card(huCard.getType(), huCard.getIndex()-1))&&
					clones.remove(new Card(huCard.getType(), huCard.getIndex()+1))
					) {
				boolean isHu = HandUtils.isHuPai(clones);
				if(isHu) {
					if(clones.remove(huCard)) {
						return isJiaHu(clones, huCard);
					}
					return true;
				}
			}
		}
		return false;
	} 
	
	public static void main(String[] args) {
//		JinUtils.getAll3Cards(true);
		String cardsStr =  "1-2;1-2;1-3;1-3;2-3;2-3;2-4;2-4;3-2;3-2;3-3;3-3;2-7;";
		Vector<Card> cards = testCard(cardsStr);
		
		long now = System.currentTimeMillis();
		System.err.println(getTingCards(cards));
		System.err.println(System.currentTimeMillis() - now);
//		System.err.println(getAnYouCard(cards, jinPai));
//		System.err.println(KdUtils.getOutCardForTing(cards, jinPai));
	}
}
